package setting

import (
	"encoding/json"
	"fmt"
	"onvif_server/internal/model"
	"reflect"
	"strconv"
	"strings"
	"sync/atomic"
)

const (
	TypeString  = "string"
	TypeStrings = "[]string"
	TypeInt     = "int"
	TypeInts    = "[]int"
	TypeBool    = "bool"
)

type smType interface {
	int | string
}

type sModel struct {
	*model.Setting
	value atomic.Pointer[any]
}

func getValue(typ string, val string) (_ any, err error) {
	switch typ {
	case TypeBool:
		if val == "1" || val == "true" {
			return true, nil
		}
		return false, nil
	case TypeString:
		return val, nil
	case TypeStrings:
		_data := make([]string, 0)
		if val == "" {
			return _data, nil
		}
		err = json.Unmarshal([]byte(val), &_data)
		return _data, err
	case TypeInt:
		if val == "" {
			return 0, nil
		}
		var _v int64
		_v, err = strconv.ParseInt(val, 10, 64)
		return int(_v), err
	case TypeInts:
		_data := make([]int, 0)
		if val == "" {
			return _data, nil
		}
		arr := strings.Split(val, ",")
		for i := range arr {
			_v, _err := strconv.ParseInt(arr[i], 10, 64)
			if _err == nil {
				_data = append(_data, int(_v))
			}
		}
		return _data, nil
	default:
		return nil, ErrorType
	}
}

func toValue(data any) (res string, err error) {
	v := reflect.TypeOf(data)
	switch v.String() {
	case TypeString:
		return data.(string), nil
	case TypeBool:
		_res := "0"
		if data == true {
			_res = "1"
		}
		return _res, nil
	case TypeStrings:
		var _res []byte
		_res, err = json.Marshal(data)
		return string(_res), err
	case TypeInt:
		return fmt.Sprintf("%d", data), nil
	case TypeInts:
		res = ""
		for _, d := range data.([]int) {
			res = fmt.Sprintf("%s,%d", res, d)
		}
		if len(res) > 0 {
			res = res[1:]
		}
		return res, nil
	default:
		return "", ErrorType
	}
}
